import { Message } from '@arco-design/web-react';
import { useMemoizedFn } from 'ahooks';
import { persist } from 'codeck';
import { useLayoutEffect, useState } from 'react';
import FileSaver from 'file-saver';
import isHotkey from 'is-hotkey';
import {
  CodeCompiler,
  useNodeStore,
  useStageStore,
  useFileStore,
} from 'codeck';
import { openRunCodeModal } from '../modal/RunCode';

/**
 * @returns 持久化相关逻辑
 */


export function usePersist() {
  const [fileHandle, setFileHandle] = useState<FileSystemFileHandle | null>(
    null
  );


  const currentFileName = fileHandle?.name ?? '本地缓存';

  const handleRun = useMemoizedFn(() => {
    const compiler = new CodeCompiler();
    compiler.useSkypack = true;
    openRunCodeModal(compiler.generate());
  });

  const open = useMemoizedFn(async () => {
    if (!window.showOpenFilePicker) {
      Message.error({
        content: '浏览器不支持调用系统文件功能，建议使用最新Chorem/Edge浏览器',
        style: {
          marginTop: 45
        }
      })
      return;
    }
    const [fileHandle] = await window.showOpenFilePicker({
      types: [
        {
          description: 'NODA节点文件',
          accept: {
            'application/noda': ['.noda'],
          },
        },
      ],
      excludeAcceptAllOption: true,
      multiple: false,
    });

    setFileHandle(fileHandle);

    const fileData = await fileHandle.getFile();
    const raw = await fileData.text();
    useFileStore.setState({
      codeckPersistMap: JSON.parse(raw),
    });
    persist.load();
    persist.NodeHistory = [persist.getFileData()];
  });

  const openNode = useMemoizedFn(async () => {
    if (!window.showOpenFilePicker) {
      Message.error({
        content: '浏览器不支持调用系统文件功能，建议使用最新Chorem/Edge浏览器',
        style: {
          marginTop: 45
        }
      })
      return;
    }
    const [fileHandle] = await window.showOpenFilePicker({
      types: [
        {
          description: 'NODA节点配置文件',
          accept: {
            'application/js': ['.js', '.ts'],
          },
        },
      ],
      excludeAcceptAllOption: true,
      multiple: false,
    });

    const fileData = await fileHandle.getFile();
    const raw = await fileData.text();

    if (raw)
      Message.success({
        content: '成功导入外部节点',
        style: {
          marginTop: 45
        }
      })
    persist.loadNode(raw);
  });


  const openURLNode = useMemoizedFn(async (url: string) => {
    console.log(url+"cccccccccc")
    if (!url) return;

    const nodejs = await (await fetch(url)).text();
    if (nodejs)
      Message.success({
        content: '成功导入外部节点',
        style: {
          marginTop: 45
        }
      })
    persist.loadNode(nodejs);
  });

  const save = useMemoizedFn(async () => {
    if (fileHandle) {
      await writeFile(fileHandle, JSON.stringify(persist.getFileData()));
    }
    persist.saveIntoLocalStorage();
    Message.success({
      id: "save",
      content: '已自动保存',
      style: {
        marginTop: 45
      }
    })
  });

  const newlyBuilt = useMemoizedFn(async () => {
    if (window.confirm("你确定要删除本地节点文件吗？确认后将删除缓存并刷新编辑器【不可恢复】")) {
      persist.removeIntoLocalStorage();
      location.reload();
    }
  });


  const saveAs = useMemoizedFn(() => {
    // 创建文件
    const raw = JSON.stringify(persist.getFileData());
    const blob = new Blob([raw], { type: 'text/plain;charset=utf-8' });
    FileSaver.saveAs(blob, `Box3-${Date.now()}.noda`);
  });

  useLayoutEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (isHotkey('mod+s', e)) {
        e.preventDefault();
        e.stopPropagation();
        save();
      }
      if (isHotkey('mod+z', e)) {
        e.preventDefault();
        e.stopPropagation();
        persist.setNodeHistory(false);
      }
      if (isHotkey('mod+y', e)) {
        e.preventDefault();
        e.stopPropagation();
        persist.setNodeHistory(true);
      }
    };

    window.addEventListener('keydown', handleKeyDown);

    return () => {
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, []);

  return { open, openNode, save, saveAs, currentFileName, handleRun, newlyBuilt, openURLNode };
}

async function writeFile(fileHandle: FileSystemFileHandle, contents: string) {
  // Create a FileSystemWritableFileStream to write to.
  const writable = await fileHandle.createWritable();

  // Write the contents of the file to the stream.
  await writable.write(contents);

  // Close the file and write the contents to disk.
  await writable.close();
}
